const { exec } = require('child_process');
const si = require('systeminformation');
const os = require('os');

class ComputerService {
    getCPUId() {
        return new Promise((resolve, reject) => {
            if (os.platform() === 'win32') {
                // Windows
                exec('wmic cpu get processorid', (error, stdout) => {
                    if (error) return reject(error);
                    const lines = stdout.trim().split('\n');
                    resolve(lines.length > 1 ? lines[1].trim() : 'Unknown');
                });
            } else if (os.platform() === 'darwin') {
                // macOS
                exec('sysctl -n machdep.cpu.brand_string', (error, stdout) => {
                    if (error) return reject(error);
                    resolve(stdout.trim());
                });
            } else {
                // Linux
                exec("cat /proc/cpuinfo | grep 'processor\\|model name' | head -n 1", (error, stdout) => {
                    if (error) return reject(error);
                    resolve(stdout.trim().split(':')[1]?.trim() || 'Unknown');
                });
            }
        });
    }

    async getNewWork() {
        try {
            // 获取所有网络接口信息
            const interfaces = await si.networkInterfaces();

            // 根据不同平台执行相应命令获取路由表
            const routeTable = await new Promise((resolve, reject) => {
                const cmd = process.platform === 'win32'
                    ? 'route print'
                    : process.platform === 'darwin'
                        ? 'netstat -rn'
                        : 'ip route show';

                exec(cmd, (error, stdout) => {
                    if (error) reject(error);
                    else resolve(stdout);
                });
            });

            // 解析路由表获取默认网关
            let defaultGateway = null;

            if (process.platform === 'win32') {
                // Windows 路由表解析
                const lines = routeTable.split('\n');
                let inIPv4Section = false;

                for (const line of lines) {
                    if (line.includes('IPv4 Route Table')) {
                        inIPv4Section = true;
                        continue;
                    }

                    if (line.includes('IPv6 Route Table')) {
                        inIPv4Section = false;
                        continue;
                    }

                    if (inIPv4Section && line.trim().startsWith('0.0.0.0')) {
                        const parts = line.trim().split(/\s+/);
                        if (parts.length >= 3) {
                            defaultGateway = parts[2];
                            break;
                        }
                    }
                }
            } else if (process.platform === 'darwin') {
                // macOS 路由表解析
                const regex = /default\s+([^\s]+)\s+([^\s]+)/;
                const match = routeTable.match(regex);
                if (match) defaultGateway = match[1];
            } else {
                // Linux 路由表解析
                const regex = /default\s+via\s+([^\s]+)\s+dev\s+([^\s]+)/;
                const match = routeTable.match(regex);
                if (match) defaultGateway = match[1];
            }

            // 构建MAC地址到网关的映射
            const macToGateway = new Map();

            interfaces.forEach(iface => {
                // 优先使用网卡自身的gateway4字段
                let gateway = iface.gateway4;

                // 如果网卡没有指定网关，使用系统默认网关
                if (!gateway && defaultGateway) {
                    gateway = defaultGateway;
                }

                if (iface.mac && iface.mac !== '00:00:00:00:00:00') {
                    macToGateway.set(iface.mac, gateway || 'Unknown');
                }
            });

            return Object.fromEntries(macToGateway);
        } catch (error) {
            console.error('获取网关信息时出错:', error);
            return {};
        }
    }

    getMacAddresses() {
        const interfaces = os.networkInterfaces();
        const macs = [];
        Object.keys(interfaces).forEach((ifname) => {
            interfaces[ifname].forEach((iface) => {
                if (!iface.internal && iface.mac !== '00:00:00:00:00:00') {
                    macs.push({
                        interface: ifname,
                        mac: iface.mac
                    });
                }
            });
        });

        return macs;
    }

    getDiskSerialNumber() {
        return new Promise((resolve, reject) => {
            if (os.platform() === 'win32') {
                // Windows
                exec('wmic diskdrive get serialnumber', (error, stdout) => {
                    if (error) return reject(error);
                    const lines = stdout.trim().split('\n');
                    resolve(lines.length > 1 ? lines[1].trim() : 'Unknown');
                });
            } else if (os.platform() === 'darwin') {
                // macOS
                exec('diskutil info / | grep "Volume UUID"', (error, stdout) => {
                    if (error) return reject(error);
                    resolve(stdout.trim().split(':')[1]?.trim() || 'Unknown');
                });
            } else {
                // Linux (需要 root 权限)
                exec('hdparm -i /dev/sda | grep SerialNo', (error, stdout) => {
                    if (error) {
                        // 尝试 lsblk 命令
                        exec('lsblk -d -o NAME,SERIAL', (err, out) => {
                            if (err) return reject(err);
                            resolve(out.trim().split('\n')[1]?.split(/\s+/)[1] || 'Unknown');
                        });
                        return;
                    }
                    resolve(stdout.trim().split('=')[1]?.trim() || 'Unknown');
                });
            }
        });
    }


    getGatewayAddress() {
        return new Promise((resolve, reject) => {
            if (os.platform() === 'win32') {
                // Windows
                exec('route print', (error, stdout) => {
                    if (error) return reject(error);
                    const lines = stdout.split('\n');
                    const gatewayLine = lines.find(line =>
                        line.includes('0.0.0.0') &&
                        line.includes('0.0.0.0') &&
                        !line.includes('On-link')
                    );

                    if (gatewayLine) {
                        const parts = gatewayLine.trim().split(/\s+/);
                        resolve(parts[2] || 'Unknown');
                    } else {
                        resolve('Unknown');
                    }
                });
            } else {
                // Linux/macOS
                exec('ip route show default', (error, stdout) => {
                    if (error) {
                        // 备用命令
                        exec('netstat -rn | grep default', (err, out) => {
                            if (err) return reject(err);
                            const parts = out.trim().split(/\s+/);
                            resolve(parts[1] || 'Unknown');
                        });
                        return;
                    }

                    const parts = stdout.trim().split(' ');
                    const gatewayIndex = parts.indexOf('via');
                    resolve(gatewayIndex > -1 ? parts[gatewayIndex + 1] : 'Unknown');
                });
            }
        });
    }

    async getGatewayMacAddress(gateway) {
        try {
            if (!gateway) {
                gateway = await this.getGatewayAddress();
            }

            if (gateway === 'Unknown') {
                return 'Unknown';
            }

            return new Promise((resolve, reject) => {
                if (os.platform() === 'win32') {
                    // Windows
                    exec('arp -a', (error, stdout) => {
                        if (error) return reject(error);
                        const lines = stdout.split('\n');
                        const gatewayLine = lines.find(line =>
                            line.includes(gateway) &&
                            !line.includes('incomplete')
                        );

                        if (gatewayLine) {
                            const parts = gatewayLine.trim().split(/\s+/);
                            resolve(parts[1] || 'Unknown');
                        } else {
                            resolve('Unknown');
                        }
                    });
                } else {
                    // Linux/macOS
                    exec(`arp -n ${gateway}`, (error, stdout) => {
                        if (error) {
                            // 备用命令
                            exec(`ip neighbor show ${gateway}`, (err, out) => {
                                if (err) return reject(err);
                                const parts = out.trim().split(' ');
                                const macIndex = parts.indexOf('lladdr');
                                resolve(macIndex > -1 ? parts[macIndex + 1] : 'Unknown');
                            });
                            return;
                        }

                        const parts = stdout.trim().split(/\s+/);
                        resolve(parts[2] || 'Unknown');
                    });
                }
            });
        } catch (error) {
            return 'Unknown';
        }
    }

    // 获取网关集（interface IP => gateway IP）
    getGatewayMap() {
        return new Promise((resolve, reject) => {
            if (os.platform() === "win32") {
            exec("route print", (error, stdout) => {
                if (error) return reject(`获取路由表失败: ${error.message}`);

                const lines = stdout
                .split("\n")
                .filter(
                    (line) =>
                    /^\s*0\.0\.0\.0\s+0\.0\.0\.0/.test(line) &&
                    !line.includes("On-link")
                );

                const gatewayMap = {};
                lines.forEach((line) => {
                const parts = line.trim().split(/\s+/);
                if (parts.length >= 4) {
                    const interfaceIp = parts[3];
                    const gatewayIp = parts[2];
                    if (interfaceIp && gatewayIp) {
                    gatewayMap[interfaceIp] = gatewayIp;
                    }
                }
                });

                resolve(gatewayMap);
            });
            } else {
            exec("ip route show default", (error, stdout) => {
                if (!error && stdout) {
                const parts = stdout.trim().split(" ");
                const gatewayIndex = parts.indexOf("via");
                const gateway = gatewayIndex > -1 ? parts[gatewayIndex + 1] : null;
                return resolve(gateway ? { [gateway]: gateway } : {});
                }

                exec("netstat -rn | grep default", (err, out) => {
                if (err) return reject(`获取默认路由失败: ${err.message}`);
                const parts = out.trim().split(/\s+/);
                const gateway = parts[1];
                resolve(gateway ? { [gateway]: gateway } : {});
                });
            });
            }
        });
    }
    // 获取所有 IPv4 网卡详细信息
    async getNetworkDetails() {
        const interfaces = os.networkInterfaces();
        const infoList = [];

        // 获取网关（IP -> 网关）
        const gatewayMap = await this.getGatewayMap().catch((err) => {
            console.error("获取网关映射失败:", err.message);
            return {};
        });

        const gatewayIps = [...new Set(Object.values(gatewayMap))];

        // 获取网关 MAC 地址
        const gatewayMacMap = {};
        for (const gw of gatewayIps) {
            try {
                const mac = await this.getGatewayMacAddress(gw);
                if (mac) gatewayMacMap[gw] = mac;
            } catch (error) {
                console.warn(`获取网关 ${gw} 的 MAC 地址失败:`, error.message);
            }
        }

        // 收集符合条件的网络接口信息
        for (const ifname in interfaces) {
            for (const iface of interfaces[ifname]) {
                if (
                !iface.internal &&
                iface.mac !== "00:00:00:00:00:00" &&
                iface.family === "IPv4"
                ) {
                const gatewayIp = gatewayMap[iface.address] || "Unknown";
                const gatewayMac = gatewayMacMap[gatewayIp] || "Unknown";

                infoList.push({
                    ip: iface.address,
                    interface: ifname,
                    mac: iface.mac,
                    gateway: gatewayIp,
                    gatewayMac: gatewayMac,
                });
                }
            }
        }

        return infoList;
    }
    // 获取网卡信息字符串
    async getNetWorkToString() {
        try {
            const cpuId = await this.getCPUId();
            const diskSerial = await this.getDiskSerialNumber();
            const networkDetails = await this.getNetworkDetails();

           const formatMac = (mac) => {
                return mac.replace(/[:\-]/g, '').toUpperCase(); // 去除冒号和横线并转为大写
            };

            const fingerprints = networkDetails.map((nicInfo) => {
                const formattedMac = formatMac(nicInfo.mac);
                const formattedGatewayMac = formatMac(nicInfo.gatewayMac);

                return `CPU:${cpuId};NC:${formattedMac};HD:${diskSerial}@${nicInfo.gateway}^${formattedGatewayMac}`;
            });

            const fullString = fingerprints.join("$");

            return fullString;
        } catch (error) {
            return "";
        }
    }

}



module.exports = {
    ComputerService,
    computerService: new ComputerService()
};

